package com.gpj.learn.rabbitmq.common;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DefaultConsumer;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;

/**
 * @className RabbitUtil
 * @description
 *   TODO
 * @author GPJ
 * @date 2021/5/30 12:16
 * @version 1.0
 **/
@Slf4j
public class RabbitUtil {
	private static Map<Channel, Connection> map = new HashMap<>();

	/* ---------------------- 创建connection以及channel ---------------------- */
	public static Channel createChannel(String queueName){
		Channel channel = createChannel();
		try {
			// 创建队列
			channel.queueDeclare(
					queueName, // 队列名称
					false, // 是否持久化,false-不持久化
					false, // 是否队列私有化,false-非私有化,全部消费者均可消费;true-私有化,第一次拥有该队列的消费者才可以使用
					false, // 是否自动删除,false-连接停止之后不自动删除该队列
					null); // 额外参数
			return channel;
		} catch (IOException e) {
			log.error("创建队列[{}]失败:{}", queueName, e.toString(), e);
		}
		return null;
	}

	public static Channel createChannel(){
		try {
			ConnectionFactory factory = new ConnectionFactory();
			factory.setHost(CommonConstants.RABBITMQ_HOST);
			factory.setPort(CommonConstants.RABBITMQ_PORT);
			factory.setUsername(CommonConstants.RABBITMQ_USER);
			factory.setPassword(CommonConstants.RABBITMQ_PASSWORD);
			factory.setVirtualHost(CommonConstants.RABBITMQ_VIRTUALHOST);

			Connection connection = factory.newConnection();

			// 获取通道
			Channel channel = connection.createChannel();
			map.put(channel, connection);
			return channel;
		} catch (TimeoutException | IOException e) {
			log.error("创建channel失败:{}", e.toString(), e);
		}
		return null;
	}

	/* ---------------------- 发送消息 ---------------------- */
	/*public static boolean sendMessage(Channel channel, String queueName, String message){
		try {
			channel.basicPublish("", queueName, null, message.getBytes());
			return true;
		} catch (IOException e) {
			log.error("消息发送失败:{}", e.toString(), e);
		}
		return false;
	}*/

	/* ---------------------- 消费消息 ---------------------- */
	public static void consumeMessage(Channel channel, String queueName, DefaultConsumer consumer){
		try {
			channel.basicConsume(queueName, false, consumer);
		} catch (IOException e) {
			log.error("消息消费失败:{}", e.toString(), e);
		}
	}

	/* ---------------------- 关闭资源 ---------------------- */
	public static void close(Channel channel){
		if(channel == null) return;
		try {
			if (map.containsKey(channel)) {
				channel.close();
				map.get(channel).close();
			}else{
				channel.close();
			}
		} catch (TimeoutException | IOException e) {
			log.error("资源关闭失败:{}", e.toString(), e);
		}
	}
}
